'use strict'

let models = require('../models');
let errors = require('../../config/errors');

let FestivalStatus = models.FestivalStatus;
let AttendanceRuleDao = models.AttendanceRuleDao;
let Festival = models.Festival;
let FestivalDao = models.FestivalDao;
let SchoolDao = models.SchoolDao;
let GradeDao = models.GradeDao;
let NatureClassDao = models.NatureClassDao;

function createFestival(festivalItem) {
    let festival = new Festival(festivalItem);
    festival.status = FestivalStatus.Created;

    FestivalDao.create(festival);

    return festival;
}

function detachFestival(festival) {
    FestivalDao.refresh(festival);
    festival.status = FestivalStatus.Detached;
    FestivalDao.update(festival);

    return festival;
}

function useFestival(festival) {
    FestivalDao.refresh(festival);
    festival.status = FestivalStatus.Used;
    FestivalDao.update(festival);

    return festival;
}

function getRecentFestivalOfStudent(student) {
    let natureClass = NatureClassDao.findOne({
        students: student.id
    });

    let grade = GradeDao.findOne({
        natureClasses: natureClass.id
    });

    let school = SchoolDao.findOne({
        grades: grade.id
    });

    let festivals = school.festivals;
    let today = new Date();

    // 筛选符合条件的节假日
    return festivals.filter(festival => {
        return festival.start >= today ||
            (festival.start <= today && festival.end >= today ); 
    })
    // 选出结束日期距离当日最小的节假日
    .reduce((recent, current) => {
        if ( recent == null ) {
            return current;
        }

        if ( current.end.getTime() - today.getTime() <
            recent.end.getTime() - today.getTime() ) {
            return current;
        }

        return recent;
    }, null);
}

function isInFestival(time, festivals) {
    let festival = festivals.find(festival => {
        return time >= festival.start &&
                time <= festival.end
    });

    return festival != null;
}

function addFestival(festival){
    let newfestival = new Festival();
    newfestival.name = festival.name;
    newfestival.start = festival.start;
    newfestival.end = festival.end;
    festival.applicableRules.forEach(rule=>{
        let festivalRule = AttendanceRuleDao.findOne({
            id:rule.id
        });
        newfestival.applicableRules.push(festivalRule);
    });

    FestivalDao.create(newfestival);
    return newfestival;
}

function updateFestival(festival){
    let oldfestival = FestivalDao.findOne({
        id:festival.id
    });
    oldfestival.name = festival.name;
    oldfestival.start = festival.start;
    oldfestival.end = festival.end;
    festival.applicableRules.forEach(rule=>{
        let festivalRule = AttendanceRuleDao.findOne({
            id:rule.id
        });
        oldfestival.applicableRules.push(festivalRule);
    });

    FestivalDao.create(oldfestival);
    return oldfestival;
}

function removeFestival(festival){
    festival = FestivalDao.findOne({
        id:festival.id
    });

    FestivalDao.remove(festival);
}

module.exports = {
    createFestival,
    detachFestival,
    useFestival,
    getRecentFestivalOfStudent,
    isInFestival,
    addFestival,
    updateFestival,
    removeFestival
};
